查看原文
其他

时间片,上下文,调度算法等知识点~

Java4ye Java4ye 2022-09-04

嘿嘿 小伙伴们好久不见啦~ 我又回来啦!😝

很久很久以前,有一个小伙子说了下篇要讲这个~  (幸好记下了 哈哈 不然我都不知道写到哪去了 (((φ(◎ロ◎;)φ))) )

时间片

「时间片」(timeslice)又称为“量子(quantum)” 或 “处理器片(processor slice)”  是 「分时操作系统」 分配给每个正在运行的进程微观上的一段CPU时间(在抢占内核中是:从进程开始运行直到被抢占的时间)。

时间片由 操作系统内核 的 调度程序 分配给每个进程。首先,内核会给每个进程分配相等的初始时间片,然后每个进程轮番地执行相应的时间,当所有进程都处于时间片耗尽的状态时,内核会重新为每个进程计算并分配时间片,如此往复  ——《百度百科》

简单来说就是将 CPU的运行时间切分出来,分配给不同的程序去运行~ 😋

进程调度算法

如下~

这里简单介绍下这个 「先来先服务」, 「短作业」「时间片轮转」 ~

小伙伴们可以大致了解下~

先来先服务(FCFS)

CPU 从就绪队列中获取最早进入该队列的进程,为其分配 CPU 资源并运行

短作业

每次运行时从队列中选一个预估运行时间最短的 , 可提高 CPU 整体的利用率和系统运行效率, 会导致某些大任务 长时间得不到调度

时间片轮转

按照 先来先服务 原则,从就绪队列中取出一个任务,并为其分配一定的 CPU 时间片去运行, 使用完时间片后由一个「时间计数器」发出 时钟中断请求,「调度器」在收到时钟中断请求后,停止该进程,并将它放到就绪队列的 「队尾」,接着从 「队首」 取出一个任务并为其分配 CPU 时间片去运行


上下文

经常听到的就是上下文切换~  还有 Spring 的上下文之间,应用上下文 等等~

还有 这位同学,请你结合上下文,回答下面这个问题:“朱自清的《背影》:我买几个橘子去。你就在此地,不要走动。” 中买橘子是啥意思?

哈哈哈~  不知道小伙伴有没有悟到呢 ,买橘子中,「结合上下文」,我们可以很快明白就是 在这篇文章中查找信息~

而程序中的上下文,无非就是程序的运行环境,比如

进程/线程 的上下文切换

上下文切换指的是 「内核(操作系统的核心)在 CPU 上对进程或者线程进行切换」 。上下文「切换过程中的信息被保存在进程控制块」(PCB-Process Control Block)中。PCB 又被称作切换帧(SwitchFrame)。上下文切换的信息会一直被保存在CPU的内存中,直到被再次使用 ——《百度百科》

Spring 的上下文 ApplicationContext

我们在使用 Springboot 的时候,经常需要去获取 Spring 的上下文 ApplicationContext 来获取 Spring 容器创建的对象呀,配置信息等~

比如这样子~

/**
 * @author 公众号:Java4ye
 */
@Component
public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(SpringUtil.applicationContext == null) {
            SpringUtil.applicationContext = applicationContext;
        }
    }

    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }

    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }
}

使用时就可以通过这样获取到 Spring 容器管理的对象了~

 A a = SpringUtil.getBean(A.class);

这里的上下文可以理解为 Spring 的容器环境~ 😄

咳咳~ 插个题外话~

怎么将对象交给 Spring 容器管理呢?

哈哈哈  这里简单带过一下~

  1. @Bean 注解
  2. 实现 BeanFactoryPostProcessor 接口    (这可是把牛刀!~  咳咳 后面 讲 Spring 再带上~  坑🕳😝)

xml 就不说啦,老古董的方式了


咳咳 不唠嗑了 说完最后一点赶紧好好写线程了😂 (知识点咋那么多呀)

进程,线程,协程

关系如图:

「进程 是 操作系统分配和调度的基本单位」

「线程 是 操作系统调度的最小单元」

每个进程中至少有一个线程在运行!

为什么要设计出线程呢?

肯定是进程有大缺点啦 😄  比如

  1. 并发 ,我们知道进程都有自己独立的内存空间,这样的话多进程之间数据的同步就变得很麻烦啦
  2. 创建和销毁进程的开销特别大,看上图就可以发现啦~(那么多东西)

为了减少系统开销,就有了这个线程啦,可以看到线程之间相互隔离,但是共享进程中的资源 ,可以解决数据同步问题

那为啥还要设计协程呢?

线程虽然比进程少了很大部分的开销,但是仍然有它的问题

比如

  1. 线程的创建和销毁

  2. 线程的切换开销

其实这个在 Java 里已经有很成熟的解决办法啦 ~   「线程池」  ,「Netty」

线程这个小家伙,外号 「轻量级进程」  , 它有自己的 堆栈,程序计数器,寄存器等 不共享的信息~  😄

如果数量过多的话,不仅仅会有内存上的压力,他们之间的竞争带来的系统开销也是一个大问题!

而在当今 「高并发」 时代~   ,还有没有更灵活的方式来提高系统的并发量呢?

当然有,这就是到协程的登场啦!

协程又称 👉  「用户态线程」,没有上下文切换等系统开销,效率非常高!

而且占用内存非常少,线程是 MB 级别的,而它是 KB 级别的

后面再多做些调研再和大家分享这个协程~ 😝

总结

最近讲的知识点 大致如下 😝

下篇正式进入线程啦~ 😝

下期见啦各位!😝



带你从CPU看到进程~(硬核)



Java中的锁居然有这么多!


我理清楚要怎么写并发啦~ (小思考)


终于来到 ConcurrentHashMap 了~



谢谢可爱又帅气的大佬们的观看!祝您 天天开心!😄  


感谢您的关注!您的每个关注,都是博主 肝肝肝的动力 😝




您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存